use common::{base::id_generator, utils::time_utils};
use std::fmt::Debug;
use std::io::Write;
use tracing::{
    field::{Field, Visit},
    span::{self, Attributes, Record},
    Event, Id, Level, Metadata, Subscriber,
};
// use tracing_appender::{non_blocking::NonBlocking, rolling::RollingFileAppender};

pub(super) struct LoggerSubscriber {
    pub(super) level: Level,
}

struct FieldVisitor {
    buffer: Vec<u8>,
}

impl Visit for FieldVisitor {
    fn record_debug(&mut self, field: &Field, value: &dyn Debug) {
        if field.name() == "message" {
            write!(&mut self.buffer, "{:?}", value).expect("打印日志失败！");
        }
    }
}

impl LoggerSubscriber {
    const TRACE_STR: &str = "TRACE";
    const DEBUG_STR: &str = "DEBUG";
    const INFO_STR: &str = " INFO";
    const WARN_STR: &str = " WARN";
    const ERROR_STR: &str = "ERROR";

    pub fn new(level: Level) -> Self {
        LoggerSubscriber { level }
    }

    fn level_fmt(level: Level) -> &'static str {
        match level {
            Level::TRACE => Self::TRACE_STR,
            Level::DEBUG => Self::DEBUG_STR,
            Level::INFO => Self::INFO_STR,
            Level::WARN => Self::WARN_STR,
            Level::ERROR => Self::ERROR_STR,
        }
    }
}

impl Subscriber for LoggerSubscriber {
    fn enabled(&self, metadata: &Metadata<'_>) -> bool {

      

        *metadata.level() <= self.level
    }

    fn new_span(&self, span: &Attributes<'_>) -> Id {
        span::Id::from_u64(id_generator::gen_id() as u64)
    }
    fn record(&self, span: &Id, values: &Record<'_>) {}

    fn record_follows_from(&self, span: &Id, follows: &Id) {}

    fn event(&self, event: &Event<'_>) {
        let mut visitor = FieldVisitor { buffer: Vec::new() };
        write!(
            &mut visitor.buffer,
            "{} {} xport {} {}: ",
            time_utils::cur_time_str(),
            Self::level_fmt(*event.metadata().level()),
            event.metadata().file().unwrap(),
            event.metadata().line().unwrap()
        )
        .expect("打印日志失败！");

        // 打印 内存
        event.record(&mut visitor);
        write!(&mut visitor.buffer, "\n").expect("打印日志失败！");

        super::append_log(visitor.buffer);
    }
    fn enter(&self, span: &Id) {}
    fn exit(&self, span: &Id) {}
}
